﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using blackhouse.BlackApart.Business.Apartments;
using blackhouse.BlackApart.Web;
using blackhouse.BlackApart.Business.Opinions;
using blackhouse.BlackApart.Business;
using blackhouse.BlackApart.Business.Prices;
using System.Globalization;
using mojoPortal.Web.Framework;
using blackhouse.JavaScript.JQuery;
using blackhouse.BlackApart.Web.Navigation;
using blackhouse.BlackApart.Business.Reservations;

namespace blackhouse.Aparts.Web.Modules {
    public partial class ApartmentGroupLine : System.Web.UI.UserControl {

        #region Fields

        private IApartmentGroup group;
        private IApartmentPrice price;
        //private double totalPrice;
        private StatisticsOpinion opinions;
        private Factory factory;
        private SearchState queryState = SearchState.GetFromContext();

        #endregion

        #region Properties

        private Factory Factory {
            get {
                if (this.factory == null)
                    this.factory = Factory.Instance();
                return this.factory;
            }
        }

        public int GetTrimDescriptionLength {
            get {
                return ConfigHelper.GetIntProperty("DescriptionLength", 360);
            }
        }

        #endregion

        #region Event Handlers

        protected override void OnLoad(EventArgs e) {
            base.OnLoad(e);

            this.AddJs();
        }

        #endregion

        #region Methods

        private void AddJs() {

            ClientScriptManager jsManager = Page.ClientScript;
            string scriptName = "prettyPhoto";
            string scriptSrc = "/prettyphoto/js/jquery.prettyPhoto.js";
            if (!jsManager.IsClientScriptIncludeRegistered(scriptName)) {
                jsManager.RegisterClientScriptInclude(scriptName, scriptSrc);
            }

            JQueryLibraries jql = new JQueryLibraries();
            jql.IncludeJQueryTipsy();
            jql.IncludeFileBasedOnJQuery("blackhouse.Aparts.Web.Scripts.displayApartmentLine.js,blackhouse.Aparts.Web");
        }

        public void PopulateControl(IApartmentGroup group) {
            this.PopulateControl(group, null);
        }

        public void PopulateControl(IApartmentGroup group, Variant variant) {
            this.SetInstance(group, variant);

            if (variant != null)
                this.PopulateRoomsCount(variant.ApartmentCount);

            this.imgMainPhoto.ImageUrl = UrlUtils.GetDbImageUrl("Apartment-photo", group.MainPhoto.PhotoName, new System.Drawing.Size(220, 220));
            this.imgMainPhoto.AlternateText = group.Name + " - " + group.MainPhoto.Category + " - " + group.MainPhoto.Description;

            this.ltlOpinion.Text = this.opinions.GetAverageRatingAsText();
            this.ltlOpinionText.Text = this.opinions.GetAverageRatingText();

            this.lnkToOpinions.NavigateUrl = UrlUtils.GetOpinionsUrl(this.Factory.GetPreFolderEvaluation(), this.group, null, 0);
            this.lnkToOpinions.Text = this.opinions.BasedOnNumberOfOpinions().ToString();
            this.lnkToOpinions.ToolTip = this.lnkToOpinions.ToolTip + " - " + this.group.Name;

            if (queryState.IsSet && queryState.PeopleCount <= this.group.NumberOfPeople) {
                this.pnlPeopleOuter.Width = Unit.Pixel(this.group.NumberOfPeople * 11);
                this.pnlPeople.Width = Unit.Pixel(this.queryState.PeopleCount * 11);
            }
            else {
                this.pnlPeople.Width = Unit.Pixel(this.group.NumberOfPeople * 11);
            }
            string lnkPeople_tooltip = GetGlobalResourceObject("Aparts", "apartmentsPeopleCount").ToString();
            if (!string.IsNullOrEmpty(lnkPeople_tooltip) && lnkPeople_tooltip.Contains("{0}"))
                this.lnkPeople.ToolTip = string.Format(lnkPeople_tooltip, this.group.NumberOfPeople);

            if (this.queryState.IsSet) {
                this.lblPriceSet.Visible = true;
                this.lblPricePersonNight.Value = this.price.GetPricePerNight();
            }
            else {
                this.lblPriceNoSet.Visible = true;
                this.lblPricePersonNight.Precision = 0;
                this.lblPricePersonNight.Value = this.price.GetPromoPriceFrom(group);
            }

            if (queryState.IsSet) {
                this.pnlPriceAll.Visible = true;
                if (variant.Price.GetRabatValue() < 0) {
                    this.lblPriceAllTotal.Visible = false;
                    this.lblNewPriceAll.Visible = true;
                    this.pnlOldPrice.Visible = true;
                    this.lblPrevPriceAll.Value = this.price.GetPriceWithoutRabat();
                    this.pnlPricePerNight.Visible = false;
                    this.pnlDiscount.Visible = true;
                    this.ltlDiscountValue.Text = string.Format("{0}%", variant.Price.GetRabatValue());
                    IPriceRabat[] rabats = variant.Price.GetAssociacedRabats();
                    if (rabats.Length == 1)
                        this.ltlDiscountName.Text = variant.Price.GetAssociacedRabats()[0].RabatName;
                    else if (rabats.Length > 1)
                        this.ltlDiscountName.Text = String.Join("<br />", rabats.Select(p => "* " + p.RabatName).ToArray());

                }
                this.lblPriceAll.Value = this.price.GetPrice();

                this.pnlAllNights.Visible = true;
                int nights = (int)(this.queryState.DepartureDate.Date - this.queryState.ArrivalDate.Date).TotalDays;
                string nightText = nights + " ";
                if (nights == 1)
                    nightText += GetGlobalResourceObject("Aparts", "nights1");
                if (nights > 1 && nights <= 4)
                    nightText += GetGlobalResourceObject("Aparts", "nights24");
                if (nights > 4)
                    nightText += GetGlobalResourceObject("Aparts", "nightsmore");
                this.lblNight.Text = nightText;
            }

            this.ltlApartmentName.Text = this.group.ShortName;

            double s = Math.Ceiling(this.group.Stars * 100 / 5);
            if (s > 100) s = 100;
            if (s < 0) s = 0;
            this.pnlStars.Width = Unit.Percentage(s);

            this.lblCity.Text = this.group.DefaultLocalization.City;
            this.lblDistrict.Text = this.group.DefaultLocalization.District;
            this.lblLocation.Text = this.group.DefaultLocalization.LocationName;
            this.lnkToPopupMap.Attributes.Add("lat", this.group.DefaultLocalization.Localization.Latitude.ToString(CultureInfo.GetCultureInfo("en-US")));
            this.lnkToPopupMap.Attributes.Add("long", this.group.DefaultLocalization.Localization.Longitude.ToString(CultureInfo.GetCultureInfo("en-US")));
            this.lnkToPopupMap.NavigateUrl = "/Pages/ShowApartmentMap.aspx?groupId=" + this.group.Id + "&iframe=true&width=960&height=550";
            this.lnkToPopupMap.ToolTip = "Lokalizacja apartamentu - " + this.group.ShortName;

            IApartmentPhoto photo = this.Factory.GetApartmentPhoto().GetApartmentTypePhotos(this.group.Id).FirstOrDefault(ap => ap.Category.Equals("schemat", StringComparison.CurrentCultureIgnoreCase));
            if (photo != null) {
                this.lnkToPopupScheme.NavigateUrl = UrlUtils.ApartmentPhotoBigImageUrl(photo.PhotoName);
                this.lnkToPopupScheme.ToolTip = group.Name + " - " + photo.Category + " - " + photo.Description;
            }
            else {
                this.lnkToPopupScheme.Visible = false;
                this.lnkToPopupMap.CssClass = this.lnkToPopupMap.CssClass.ReplaceEx("-1", "-2");
            }



            this.lblDescription.Text = GetDescription();
            this.lnkFromDescription.NavigateUrl = UrlUtils.GetApartmentTypeUrl(this.Factory.GetPreFolderEvaluation(), this.group, DisplayApartmentTypeView.Default, 0);
            this.lnkFromDescription.ToolTip = "Opis " + this.group.Name;

            this.ltlSurface.Text = this.group.AreaSize.ToString("F0");

            this.rptFields.DataSource = this.group.Fields;
            this.rptFields.DataBind();

            if (this.queryState.IsSet) {
                this.lnkBook.Visible = true;
                this.lnkBook.NavigateUrl = NavigationProvider.Instance().GetUrl(ReservationPage.GetInformationPage(this.group.Id));
                this.lnkBook.ToolTip = "Zarezerwuj apartament - " + this.group.Name;
            }
            else {
                this.lnkReservationPopup.Visible = true;
                this.lnkReservationPopup.Apartment = this.group;
            }
        }

        //[Obsolete]
        //public void PopulateControl(IApartmentGroup group, double pricePerNight, double totalPrice) {
        //    this.SetInstance(group, pricePerNight, totalPrice);

        //    this.imgMainPhoto.ImageUrl = UrlUtils.GetDbImageUrl("Apartment-photo", group.MainPhoto.PhotoName, new System.Drawing.Size(220, 220));
        //    this.imgMainPhoto.AlternateText = group.Name + " - " + group.MainPhoto.Category + " - " + group.MainPhoto.Description;

        //    this.ltlOpinion.Text = this.opinions.GetAverageRatingAsText();
        //    this.ltlOpinionText.Text = this.opinions.GetAverageRatingText();

        //    this.lnkToOpinions.NavigateUrl = UrlUtils.GetOpinionsUrl(this.Factory.GetPreFolderEvaluation(), this.group, null, 0);
        //    this.lnkToOpinions.Text = this.opinions.BasedOnNumberOfOpinions().ToString();
        //    this.lnkToOpinions.ToolTip = this.lnkToOpinions.ToolTip + " - " + this.group.Name;

        //    if (queryState.IsSet && queryState.PeopleCount <= this.group.NumberOfPeople) {
        //        this.pnlPeopleOuter.Width = Unit.Pixel(this.group.NumberOfPeople * 11);
        //        this.pnlPeople.Width = Unit.Pixel(this.queryState.PeopleCount * 11);
        //    }
        //    else {
        //        this.pnlPeople.Width = Unit.Pixel(this.group.NumberOfPeople * 11);
        //    }
        //    string lnkPeople_tooltip = GetGlobalResourceObject("Aparts", "apartmentsPeopleCount").ToString();
        //    if (!string.IsNullOrEmpty(lnkPeople_tooltip) && lnkPeople_tooltip.Contains("{0}"))
        //        this.lnkPeople.ToolTip = string.Format(lnkPeople_tooltip, this.group.NumberOfPeople);

        //    if (this.queryState.IsSet) {
        //        this.lblPriceSet.Visible = true;
        //    }
        //    else {
        //        this.lblPriceNoSet.Visible = true;
        //        this.lblPricePersonNight.Precision = 0;
        //    }
        //    this.lblPricePersonNight.Value = this.price;

        //    if (queryState.IsSet) {
        //        this.pnlPriceAll.Visible = true;
        //        this.lblPriceAll.Value = this.totalPrice;

        //        this.pnlAllNights.Visible = true;
        //        int nights = (int)(this.queryState.DepartureDate.Date - this.queryState.ArrivalDate.Date).TotalDays;
        //        string nightText = nights + " ";
        //        if (nights == 1)
        //            nightText += GetGlobalResourceObject("Aparts", "nights1");
        //        if (nights > 1 && nights <= 4)
        //            nightText += GetGlobalResourceObject("Aparts", "nights24");
        //        if (nights > 4)
        //            nightText += GetGlobalResourceObject("Aparts", "nightsmore");
        //        this.lblNight.Text = nightText;
        //    }

        //    this.ltlApartmentName.Text = this.group.ShortName;

        //    double s = Math.Ceiling(this.group.Stars * 100 / 5);
        //    if (s > 100) s = 100;
        //    if (s < 0) s = 0;
        //    this.pnlStars.Width = Unit.Percentage(s);

        //    this.lblCity.Text = this.group.DefaultLocalization.City;
        //    this.lblDistrict.Text = this.group.DefaultLocalization.District;
        //    this.lblLocation.Text = this.group.DefaultLocalization.LocationName;
        //    this.lnkToPopupMap.Attributes.Add("lat", this.group.DefaultLocalization.Localization.Latitude.ToString(CultureInfo.GetCultureInfo("en-US")));
        //    this.lnkToPopupMap.Attributes.Add("long", this.group.DefaultLocalization.Localization.Longitude.ToString(CultureInfo.GetCultureInfo("en-US")));
        //    this.lnkToPopupMap.NavigateUrl = "/Pages/ShowApartmentMap.aspx?groupId=" + this.group.Id + "&iframe=true&width=960&height=550";
        //    this.lnkToPopupMap.ToolTip = "Lokalizacja apartamentu - " + this.group.ShortName;

        //    IApartmentPhoto photo = this.Factory.GetApartmentPhoto().GetApartmentTypePhotos(this.group.Id).FirstOrDefault(ap => ap.Category.Equals("schemat", StringComparison.CurrentCultureIgnoreCase));
        //    if (photo != null) {
        //        this.lnkToPopupScheme.NavigateUrl = UrlUtils.ApartmentPhotoBigImageUrl(photo.PhotoName);
        //        this.lnkToPopupScheme.ToolTip = group.Name + " - " + photo.Category + " - " + photo.Description;
        //    }
        //    else {
        //        this.lnkToPopupScheme.Visible = false;
        //        this.lnkToPopupMap.CssClass = this.lnkToPopupMap.CssClass.ReplaceEx("-1", "-2");
        //    }



        //    this.lblDescription.Text = GetDescription();
        //    this.lnkFromDescription.NavigateUrl = UrlUtils.GetApartmentTypeUrl(this.Factory.GetPreFolderEvaluation(), this.group, DisplayApartmentTypeView.Default, 0);
        //    this.lnkFromDescription.ToolTip = "Opis " + this.group.Name;

        //    this.ltlSurface.Text = this.group.AreaSize.ToString("F0");

        //    this.rptFields.DataSource = this.group.Fields;
        //    this.rptFields.DataBind();

        //    if (this.queryState.IsSet) {
        //        this.lnkBook.Visible = true;
        //        this.lnkBook.NavigateUrl = NavigationProvider.Instance().GetUrl(ReservationPage.GetInformationPage(this.group.Id));
        //        this.lnkBook.ToolTip = "Zarezerwuj apartament - " + this.group.Name;
        //    }
        //    else {
        //        this.lnkReservationPopup.Visible = true;
        //        this.lnkReservationPopup.Apartment = this.group;
        //    }
        //}

        protected void rptFields_ItemDataBound(object sender, RepeaterItemEventArgs e) {
            switch (e.Item.ItemType) {
                case ListItemType.AlternatingItem:
                case ListItemType.Item:

                    Panel pnlField = e.Item.FindControl("pnlField") as Panel;
                    Literal ltlTitle = e.Item.FindControl("ltlTitle") as Literal;
                    Literal ltlValue = e.Item.FindControl("ltlValue") as Literal;

                    ApartmentOptionField field = e.Item.DataItem as ApartmentOptionField;

                    if (field != null) {
                        if (pnlField != null && !string.IsNullOrEmpty(field.Description))
                            pnlField.Attributes.Add("toolpop", field.Description);
                        if (ltlTitle != null)
                            ltlTitle.Text = field.Title;
                        if (ltlValue != null)
                            ltlValue.Text = field.Variant.OptionFieldToString();
                    }

                    break;

            }

        }

        private void PopulateRoomsCount(int count) {
            this.pnlMoreOne.Visible = count > 1;
            this.pnlRooms.Width = Unit.Pixel(count * 11);
            string lnkRooms_ToolTip = GetGlobalResourceObject("Aparts", "apartmentsCount").ToString();
            if (!string.IsNullOrEmpty(lnkRooms_ToolTip) && lnkRooms_ToolTip.Contains("{0}"))
                this.lnkRooms.ToolTip = string.Format(lnkRooms_ToolTip, count);

        }

        private string GetDescription() {
            object oD = this.group.GetProperty("opis");
            if (oD != null) {
                string sD = oD.ToString();
                sD = sD.ReplaceEx("<br />", "");
                sD = sD.ReplaceEx("<br>", "");
                if (sD.Length < GetTrimDescriptionLength)
                    return sD;
                else {
                    sD = sD.SubstringToWord(GetTrimDescriptionLength);
                    return sD;
                }
            }
            else return "";
        }

        private void SetInstance(IApartmentGroup group, Variant variant) {
            this.group = group;
            if (variant != null)
                this.price = variant.Price;
            else
                this.price = this.Factory.GetApartmentGroupPrice(group);
            //this.totalPrice = totalPrice;
            this.opinions = Factory.Instance().GetStatisticsOpinion();
            this.opinions.SetFilterByApartmentType(group.Id);
        }

        #endregion

    }

    internal static class ApartExt {

        public static Dictionary<string, Dictionary<ApartmentOptionFieldVariant, string>> variants = new Dictionary<string, Dictionary<ApartmentOptionFieldVariant, string>>();

        public static string OptionFieldToString(this ApartmentOptionFieldVariant variant) {
            string l = CultureInfo.CurrentCulture.Name;

            if (!variants.ContainsKey(l))
                variants[l] = new Dictionary<ApartmentOptionFieldVariant, string>();

            if (!variants[l].ContainsKey(variant))
                variants[l][variant] = HttpContext.GetGlobalResourceObject("Aparts", "optionField" + ((int)variant)).ToString();

            return variants[l][variant];
        }
    }

}